//
//  SRSportService.m
//  SportRing
//
//  Created by mykoma on 14/10/28.
//  Copyright (c) 2014年 HotOne. All rights reserved.
//

#import "SRSportBleService.h"
#import "BlueToothLib.h"
#import "SRDB.h"

#define SPORT_SLEEP_CACHED_KEY @"SPORT_SLEEP_CACHED_KEY"

@implementation SRSportBleService

+(void)addObserverForBleData
{
    [SRSportBleService handleCurrentTaskData];
    [SRSportBleService handleCurrentSportData];
    [SRSportBleService handleUnSyncSportData];
    [SRSportBleService handleSleepData];
}

+ (void)handleUnSyncSportData
{
    [[NSNotificationCenter defaultCenter] addObserverForName:NOTIFY_GET_UNSYNC_SPORT_DATA
                                                      object:nil
                                                       queue:nil
                                                  usingBlock:^(NSNotification *note)
     {
//         static const char * UUID = "\xb2\x13\x17\x1c\x05\x0d\x00\x00\xb2\x13\x17\x1c\x00\x00\x20\x00\xb2\x85\x17\x1c"
//         
//         "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
//         "\x50\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\x00\x00\x80\x8d\x52\x00"
//         "\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x01\x00\x00\x80\x8d\x52\x00"
//         "\x70\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x02\x00\x00\x01\x80\x8d\x51"
//         "\x70\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00\x80\x02\x00\x00\x01\x80\x8d\x53"
//         "\x70\x00\x00\x00\x30\x00\x00\x00\x00\x00\x00\x00\x80\x02\x00\x00\x01\x80\x8d\x55"
//         "\x70\x00\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00\x80\x03\x00\x00\x01\x80\x8d\x54"
//         "\x70\x00\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00\x80\x04\x00\x00\x01\x80\x8d\x56"
//         "\x70\x00\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00\x80\x04\x00\x00\x01\x80\x8d\x6b"
//         "\x70\x00\x00\x00\x40\x00\x00\x00\x40\x00\x00\x00\x80\x05\x00\x00\x01\x80\x8d\x7b"
//         "\x70\x00\x00\x00\x40\x00\x00\x00\x40\x00\x00\x00\x80\x05\x00\x00\x01\x80\x8d\xab"
//         "\x70\x00\x00\x00\x40\x00\x00\x00\x40\x00\x00\x00\x80\x06\x00\x00\x01\x80\x8d\xbb"
//         
//         "\xff\xff\xff\xff""\xff\xff\xff\xff""\xff\xff\xff\xff""\xff\xff\xff\xff"
//         "\x5e\x2e\x1c\x16""\x5e\x2e\x1c\x16""\x5e\x2e\x1c\x16""\x5e\x2e\x1c\x16"
//         "\x5e\x2e\x1c\x16""\x5e\x2e\x1c\x16""\x5e\x2e\x1c\x16""\x5e\x2e\x1c\x16"
//         "\x5e\x2e\x1c\x16""\x5e\x2e\x1c\x16""\x5e\x2e\x1c\x16""\x5e\x2e\x1c\x16"
//         "\x5e\x2e\x1c\x16""\x5e\x2e\x1c\x16""\x5e\x2e\x1c\x16""\x5e\x2e\x1c\x16"
//         "\x5e\x2e\x1c\x16""\x5e\x2e\x1c\x16""\x5e\x2e\x1c\x16""\x5e\x2e\x1c\x16"
//         "\x5e\x2e\x1c\x16""\x5e\x2e\x1c\x16""\x5e\x2e\x1c\x16""\x5e\x2e\x1c\x16"
//         "\x5e\x2e\x1c\x16""\x5e\x2e\x1c\x16""\x5e\x2e\x1c\x16""\x5e\x2e\x1c\x16"
//         "\x5e\x2e\x1c\x16""\x5e\x2e\x1c\x16""\x5e\x2e\x1c\x16""\x5e\x2e\x1c\x16"
//         "\x5e\x2e\x1c\x16""\x5e\x2e\x1c\x16""\x5e\x2e\x1c\x16""\x5e\x2e\x1c\x16"
//         "\x5e\x2e\x1c\x16""\x5e\x2e\x1c\x16""\x5e\x2e\x1c\x16""\x5e\x2e\x1c\x16"
//         "\x5e\x2e\x1c\x16""\x5e\x2e\x1c\x16""\x5e\x2e\x1c\x16""\x5e\x2e\x1c\x16"
//         ;
//         NSData * nsdata = [NSData dataWithBytes:UUID length:452];
//         const unsigned char * data = nsdata.bytes;
         const unsigned char * data = ((NSData *)note.object).bytes;
         
         int offset = 0;
         
         /************任务状态 BEGIN***********/
         uint32_t dateInterval;
         memcpy(&dateInterval, &data[offset], 4);
         offset += 4;
         
         uint32_t target;
         memcpy(&target, &data[offset], 4);
         offset += 4;
         
         uint32_t beginTimeInterval;
         memcpy(&beginTimeInterval, &data[offset], 4);
         offset += 4;
         
         uint32_t completeCounter;
         memcpy(&completeCounter, &data[offset], 4);
         offset += 4;
         
         uint32_t endTimeInterval;
         memcpy(&endTimeInterval, &data[offset], 4);
         offset += 4;
         
         NSDate * baseDate = [NSDate baseDate];
         NSDate * date = [baseDate dateByAddingTimeInterval:dateInterval];
         NSDate * beginTime = [baseDate dateByAddingTimeInterval:beginTimeInterval];
         NSDate * endTime = [baseDate dateByAddingTimeInterval:endTimeInterval];
         
         SRSportTask * task = [SRSportTask findTaskCINEForDay:[date formattedBy_yyyyMMdd]];
         [task configAttributesWithBlock:^(SRSportTask *aSelf) {
             aSelf.completedCounter = @(completeCounter);
             aSelf.startTime = [beginTime formattedBy_hhmmss];
             aSelf.endTime = [endTime formattedBy_hhmmss];
             aSelf.totalCounter = @(target);
         }];
         
         /************任务状态 END***********/
         
         SRDay * day = [SRDay findDayCINEForDate:date forMe:[SRMe currentUser]];
         
         // 设置月
         SRMonth * month = [SRMonth findMonthCINEForDate:date forMe:[SRMe currentUser]];
         [day configAttributesWithBlock:^(SRDay *aSelf) {
             aSelf.month = month;
         }];
         
         /************步数数据 BEGIN***********/
         
         uint32_t lastWalkCounter = 0;
         uint32_t lastRunCounter = 0;
         uint32_t lastUpstairCounter = 0;
         uint32_t lastCalorie = 0;
         uint32_t lastDistance = 0;
         
         for (int index = 0; index < 12; index ++) {
             NSData * tmpData = [[NSData alloc] initWithBytes:&data[offset] length:20];
             if (![SRSportBleService dataIsValid:tmpData]) {
                 offset += 20;
                 continue;
             }
             uint32_t temp = 0;
             
             uint32_t walkCounter;
             memcpy(&walkCounter, &data[offset], 4);
             temp = walkCounter;
             walkCounter -= lastWalkCounter;
             lastWalkCounter = temp;
             offset += 4;
             
             uint32_t runCounter;
             memcpy(&runCounter, &data[offset], 4);
             temp = runCounter;
             runCounter -= lastRunCounter;
             lastRunCounter = temp;
             offset += 4;
             
             uint32_t upstairCounter;
             memcpy(&upstairCounter, &data[offset], 4);
             temp = upstairCounter;
             upstairCounter -= lastUpstairCounter;
             lastUpstairCounter = temp;
             offset += 4;
             
             uint32_t calorie;
             memcpy(&calorie, &data[offset], 4);
             temp = calorie;
             calorie -= lastCalorie;
             lastCalorie = temp;
             offset += 4;
             
             uint32_t distance;
             memcpy(&distance, &data[offset], 4);
             temp = distance;
             distance -= lastDistance;
             lastDistance = temp;
             offset += 4;
             
             SRSportPart * sportPart = [SRSportPart findSportPartCINEForDay:day forSection:index];
             [sportPart configAttributesWithBlock:^(SRSportPart *aSelf) {
                 aSelf.walkCounter = @(walkCounter);
                 aSelf.runCounter = @(runCounter);
                 aSelf.upstairsCounter = @(upstairCounter);
                 aSelf.calorie = @(calorie);
                 aSelf.mileage = @(distance);
             }];
         }
         /************步数数据 END***********/
        
         /************环境数据 BEGIN***********/
         
         for (int index = 0; index < 12; index ++) {
             NSData * tmpData = [[NSData alloc] initWithBytes:&data[offset] length:16];
             if (![SRSportBleService dataIsValid:tmpData]) {
                 offset += 16;
                 continue;
             }
             
             uint16_t p1;
             memcpy(&p1, &data[offset], 2);
             offset += 2;
             
             uint16_t t1;
             memcpy(&t1, &data[offset], 2);
             offset += 2;
             
             uint16_t p2;
             memcpy(&p2, &data[offset], 2);
             offset += 2;
             
             uint16_t t2;
             memcpy(&t2, &data[offset], 2);
             offset += 2;
             
             uint16_t p3;
             memcpy(&p3, &data[offset], 2);
             offset += 2;
             
             uint16_t t3;
             memcpy(&t3, &data[offset], 2);
             offset += 2;
             
             uint16_t p4;
             memcpy(&p4, &data[offset], 2);
             offset += 2;
             
             uint16_t t4;
             memcpy(&t4, &data[offset], 2);
             offset += 2;
             
             SRSportPart * sportPart = [SRSportPart findSportPartForDay:day forSection:index];
             if ((p1 == 0xffff && t1 == 0xffff) || (p2 == 0xffff && t2 == 0xffff) || (p3 == 0xffff && t3 == 0xffff) || (p4 == 0xffff && t4 == 0xffff)) {
                 [SRSportPart deleteSportPart:sportPart];
                 continue;
             }
             
             [sportPart configAttributesWithBlock:^(SRSportPart *aSelf) {
                 aSelf.t1 = @(t1 * 1.0 / (2 << 13) * 165 - 40);
                 aSelf.p1 = @(p1 * 1.0 / (2 << 13) * 90 + 30 );
                 aSelf.t2 = @(t2 * 1.0 / (2 << 13) * 165 - 40);
                 aSelf.p2 = @(p2 * 1.0 / (2 << 13) * 90 + 30 );
                 aSelf.t3 = @(t3 * 1.0 / (2 << 13) * 165 - 40);
                 aSelf.p3 = @(p3 * 1.0 / (2 << 13) * 90 + 30 );
                 aSelf.t4 = @(t4 * 1.0 / (2 << 13) * 165 - 40);
                 aSelf.p4 = @(p4 * 1.0 / (2 << 13) * 90 + 30 );
             }];
         }
         /************环境数据 END***********/

         [[NSNotificationCenter defaultCenter] postNotificationName:NEW_UNSYNC_SPORT_DATA_NOTIFY object:nil];
     }];
}

+ (void)handleCurrentSportData
{
    [[NSNotificationCenter defaultCenter] addObserverForName:NOTIFY_GET_CURRENT_SPORT_DATA
                                                      object:nil
                                                       queue:nil
                                                  usingBlock:^(NSNotification *note)
     {
         const void * data = ((NSData *)note.object).bytes;
         uint32_t walkCounter;
         memcpy(&walkCounter, &data[0], 4);
         uint32_t runCounter;
         memcpy(&runCounter, &data[4], 4);
         uint32_t upstairCounter;
         memcpy(&upstairCounter, &data[8], 4);
         uint32_t calorie;
         memcpy(&calorie, &data[12], 4);
         uint32_t distance;
         memcpy(&distance, &data[16], 4);
         uint16_t pressure;
         memcpy(&pressure, &data[20], 2);
         uint16_t tempreature;
         memcpy(&tempreature, &data[22], 2);
         
         SRCurrentData * currentData = [SRCurrentData findCurrentDataCINEForMe:[SRMe currentUser]];
         [currentData configAttributesWithBlock:^(SRCurrentData *aSelf) {
             aSelf.runCounter = @(runCounter);
             aSelf.walkCounter = @(walkCounter);
             aSelf.upstairCounter = @(upstairCounter);
             aSelf.calori = @(calorie);
             aSelf.distance = @(distance);
             aSelf.pressure = @(pressure * 1.0 / (2 << 13) * 90 + 30 );
             aSelf.tempreature = @(tempreature * 1.0 / (2 << 13) * 165 - 40);
         }];
         
         [[NSNotificationCenter defaultCenter] postNotificationName:NEW_CURRENT_SPORT_DATA_NOTIFY object:nil];
     }];
}

+ (void)handleCurrentTaskData
{
    [[NSNotificationCenter defaultCenter] addObserverForName:NOTIFY_GET_CURRENT_TASK_DATA
                                                      object:nil
                                                       queue:nil
                                                  usingBlock:^(NSNotification *note)
     {
         const void * data = ((NSData *)note.object).bytes;
         uint32_t dateInterval;
         memcpy(&dateInterval, &data[0], 4);
         uint32_t target;
         memcpy(&target, &data[4], 4);
         uint32_t beginTimeInterval;
         memcpy(&beginTimeInterval, &data[8], 4);
         uint32_t completeCounter;
         memcpy(&completeCounter, &data[12], 4);
         uint32_t endTimeInterval;
         memcpy(&endTimeInterval, &data[16], 4);
         
         NSDate * baseDate = [NSDate baseDate];
         NSDate * date = [baseDate dateByAddingTimeInterval:dateInterval];
         NSDate * beginTime = [baseDate dateByAddingTimeInterval:beginTimeInterval];
         NSDate * endTime = [baseDate dateByAddingTimeInterval:endTimeInterval];
         
         SRCurrentTask * currentTask = [SRCurrentTask findCurrentTaskCINEForMe:[SRMe currentUser]];
         
         [currentTask configAttributesWithBlock:^(SRCurrentTask *aSelf) {
             aSelf.target = @(target);
             aSelf.completedCounter = @(completeCounter);
             aSelf.beginTime = [beginTime formattedBy_hhmmss];
             aSelf.endTime = [endTime formattedBy_hhmmss];
         }];
         
         SRSportTask * task = [SRSportTask findTaskCINEForDay:[date formattedBy_yyyyMMdd]];
         [task configAttributesWithBlock:^(SRSportTask *aSelf) {
             aSelf.completedCounter = @(completeCounter);
             aSelf.startTime = [beginTime formattedBy_hhmmss];
             aSelf.endTime = [endTime formattedBy_hhmmss];
             aSelf.totalCounter = @(target);
         }];
         
         [[NSNotificationCenter defaultCenter] postNotificationName:NEW_CURRENT_TASK_DATA_NOTIFY object:nil];
     }];
}

+ (void)handleSleepData
{
    [[NSNotificationCenter defaultCenter] addObserverForName:NOTIFY_GET_SLEEP_DATA
                                                      object:nil
                                                       queue:nil
                                                  usingBlock:^(NSNotification *note)
     {
//         static const char * UUID = "\xf4\x32\x16\x1c\x01\x00\x02\x00"
//         "\xA8\x33\x16\x1C\x02\x03\x05\x00"
//         "\x98\x7E\x16\x1C\x02\x32\x89\x05"
//         
//         "\xf4\x32\x17\x1c\x01\x00\x02\x00"
//         "\xA8\x33\x17\x1C\x02\x03\x05\x00"
//         "\xCC\x78\x17\x1C\x02\x06\x2C\x00"
//         "\xB0\xA3\x17\x1C\x02\x01\xE3\x01"
//         "\x98\x7E\x18\x1C\x02\x32\x89\x05"
//         "\x90\x95\x18\x1C\x02\x01\x2C\x00"
//         "\xDC\xC1\x18\x1C\x02\x01\x2C\x01"
//         "\xf4\x85\xff\x1B\x02\x08\x00\x00"
//         "\x04\x8f\xff\x1B\x02\x32\x00\x00"
//         "\x14\x90\xff\x1B\x02\x28\x00\x00"
//         "\x24\x97\xff\x1B\x02\x3c\x00\x00"
//         "\x35\x9f\xff\x1B\x02\x35\x00\x00"
//         "\x45\xa2\xff\x1B\x02\x01\x00\x00"
//         "\x55\xa7\xff\x1B\x00\x00\x00\x00"
//         "\xff\xaf\xff\xff\xff\xff\xff\xff"
//         "\xff\xb3\xff\xff\xff\xff\xff\xff"
//         "\xff\xb8\xff\xff\xff\xff\xff\xff"
//         "\x74\xab\x0f\x1c\x02\x03\x13\x00"
//         "\xB4\xCB\x18\x1c\x00\x00\x5c\x00";
//         NSData * nsdata = [NSData dataWithBytes:UUID length:88];
         NSData * nsdata = (NSData *)note.object;
         const void * data = nsdata.bytes;
         
         NSMutableData * savedData = [[[NSUserDefaults standardUserDefaults] objectForKey:SPORT_SLEEP_CACHED_KEY] mutableCopy];
         
         int offset = 0;
         
         for (int index = 0; index < nsdata.length / 8; index ++) {
             uint32_t dateInterval;
             memcpy(&dateInterval, &data[offset], 4);
             offset += 4;
             
             uint8_t type;
             memcpy(&type, &data[offset], 1);
             offset += 1;
             
             uint8_t shake;
             memcpy(&shake, &data[offset], 1);
             offset += 1;
             
             //reversed
             uint16_t reversed;
             memcpy(&reversed, &data[offset], 2);
             offset += 2;
             
             switch (type) {
                 case 0:
                 {
                     [savedData appendBytes:&dateInterval length:4];
                     [savedData appendBytes:&type length:1];
                     [savedData appendBytes:&shake length:1];
                     [savedData appendBytes:&reversed length:2];
                     
                     [SRSportBleService processSleepData:savedData];
                     savedData = [[NSData data] mutableCopy];
                 }
                     break;
                 case 1:
                 {
                     if (savedData.length > 0) {
                         [SRSportBleService handleUnsafeSleepData:savedData];
                     }
                     savedData = [[NSMutableData alloc] init];
                     [savedData appendBytes:&dateInterval length:4];
                     [savedData appendBytes:&type length:1];
                     [savedData appendBytes:&shake length:1];
                     [savedData appendBytes:&reversed length:2];
                 }
                     break;
                 case 2:
                 {
                     [savedData appendBytes:&dateInterval length:4];
                     [savedData appendBytes:&type length:1];
                     [savedData appendBytes:&shake length:1];
                     [savedData appendBytes:&reversed length:2];
                 }
                     break;
                     
                 default:
                     break;
             }
         }
         [[NSUserDefaults standardUserDefaults] setObject:savedData forKey:SPORT_SLEEP_CACHED_KEY];
         [[NSUserDefaults standardUserDefaults] synchronize];
     }];
}

+ (void)processSleepData:(NSData *)nsdata
{
    const void * data = nsdata.bytes;
    
    int offset = 0;
    
    SRSleep * sleep = nil;
    SRDay * day = nil;
    NSDate * baseDate = [NSDate baseDate];
    
    uint32_t dayInterval;
    if (nsdata == nil) {
        return;
    }
    memcpy(&dayInterval, &data[nsdata.length - 8], 4);
    NSDate * sleepDayDate = [baseDate dateByAddingTimeInterval:dayInterval];
    
    for (int index = 0; index < nsdata.length / 8; index ++) {
        uint32_t dateInterval;
        memcpy(&dateInterval, &data[offset], 4);
        offset += 4;
        
        uint8_t type;
        memcpy(&type, &data[offset], 1);
        offset += 1;
        
        uint8_t shake;
        memcpy(&shake, &data[offset], 1);
        offset += 1;
        
        //reversed
        offset += 2;
        
        NSDate * date = [baseDate dateByAddingTimeInterval:dateInterval];
        
        NSString * timeStr = [date formattedBy_yyyyMMddhhmmss];
        
        switch (type) {
            case 0:
            {
                [sleep configAttributesWithBlock:^(SRSleep *aSelf) {
                    aSelf.endTime = date;
                }];
                
                SRSleepPart * sleepPart = [SRSleepPart findPartCINEForSleep:sleep filterByTimeStr:timeStr];
                [sleepPart configAttributesWithBlock:^(SRSleepPart *aSelf) {
                    aSelf.shake = @(1);
                    aSelf.time = date;
                }];
            }
                break;
            case 1:
            {
                day = [SRDay findDayCINEForDate:sleepDayDate forMe:[SRMe currentUser]];
                [SRSleep deleteSleepForDay:day];
                sleep = [SRSleep findSleepCINEForDay:day];
                [sleep configAttributesWithBlock:^(SRSleep *aSelf) {
                    aSelf.startTime = date;
                }];
                
                SRSleepPart * sleepPart = [SRSleepPart findPartCINEForSleep:sleep filterByTimeStr:timeStr];
                [sleepPart configAttributesWithBlock:^(SRSleepPart *aSelf) {
                    aSelf.shake = @(1);
                    aSelf.time = date;
                }];
            }
                break;
            case 2:
            {
                SRSleepPart * sleepPart = [SRSleepPart findPartCINEForSleep:sleep filterByTimeStr:timeStr];
                [sleepPart configAttributesWithBlock:^(SRSleepPart *aSelf) {
                    aSelf.shake = @(shake);
                    aSelf.time = date;
                }];
            }
                break;
                
            default:
                break;
        }
    }
    
    [[NSNotificationCenter defaultCenter] postNotificationName:NEW_SLEEP_DATA_NOTIFY object:nil];
}

+ (RACSignal *)readCurrentTaskData
{
    static id observer = nil;
    [[NSNotificationCenter defaultCenter] removeObserver:observer];
    
    RACSubject * subject = [RACSubject subject];
    
    observer = [[NSNotificationCenter defaultCenter] addObserverForName:NOTIFY_RECIVED_CURRENT_TASK_DATA
                                                                 object:nil
                                                                  queue:nil
                                                             usingBlock:^(NSNotification *note)
                {
                    [subject sendNext:nil];
                }];
    
    [BlueToothLib requestSportData:0x01 withBlock:^(BOOL isTimeOut) {
        if (isTimeOut) {
            [subject sendNext:nil];
        }
    }];
    
    return subject;
}

+ (RACSignal *)readCurrentSportData
{
    static id observer = nil;
    [[NSNotificationCenter defaultCenter] removeObserver:observer];
    
    RACSubject * subject = [RACSubject subject];
    
    observer = [[NSNotificationCenter defaultCenter] addObserverForName:NOTIFY_RECIVED_CURRENT_SPORT_DATA
                                                                 object:nil
                                                                  queue:nil
                                                             usingBlock:^(NSNotification *note)
                {
                    [subject sendNext:nil];
                }];
    
    [BlueToothLib requestSportData:0x02 withBlock:^(BOOL isTimeOut) {
        if (isTimeOut) {
            [subject sendNext:nil];
        }
    }];
    
    return subject;
}

+ (RACSignal *)readUnSyncSportData
{
    static id needMoreDataObserver = nil;
    static id noMoreDataObserver = nil;
    static BOOL listening;
    listening = YES;
    [[NSNotificationCenter defaultCenter] removeObserver:needMoreDataObserver];
    [[NSNotificationCenter defaultCenter] removeObserver:noMoreDataObserver];
    
    RACSubject * subject = [RACSubject subject];
    
    noMoreDataObserver = [[NSNotificationCenter defaultCenter] addObserverForName:NOTIFY_NO_MORE_SPORT_DATA
                                                                           object:nil
                                                                            queue:nil
                                                                       usingBlock:^(NSNotification *note)
                          {
                              if (listening) {
                                  listening = NO;
                                  [subject sendNext:nil];
                              }
                          }];
    
    needMoreDataObserver = [[NSNotificationCenter defaultCenter] addObserverForName:NOTIFY_RECIVED_UNSYNC_SPORT_DATA
                                                                             object:nil
                                                                              queue:nil
                                                                         usingBlock:^(NSNotification *note)
                            {
                                [BlueToothLib requestSportData:0x04 withBlock:^(BOOL isTimeOut) {
                                    if (isTimeOut) {
                                        [subject sendNext:nil];
                                    }
                                }];
                            }];
    
    [BlueToothLib requestSportData:0x04 withBlock:^(BOOL isTimeOut) {
        if (isTimeOut) {
            [subject sendNext:nil];
        }
    }];
    
    return subject;
}

+ (RACSignal *)readSleepData
{
    static id needMoreDataObserver = nil;
    static id noMoreDataObserver = nil;
    static BOOL listening;
    listening = YES;
    [[NSNotificationCenter defaultCenter] removeObserver:needMoreDataObserver];
    [[NSNotificationCenter defaultCenter] removeObserver:noMoreDataObserver];
    
    RACSubject * subject = [RACSubject subject];
    
    noMoreDataObserver = [[NSNotificationCenter defaultCenter] addObserverForName:NOTIFY_NO_MORE_SPORT_DATA
                                                                           object:nil
                                                                            queue:nil
                                                                       usingBlock:^(NSNotification *note)
                          {
                              if (listening) {
                                  listening = NO;
                                  [subject sendNext:nil];
                              }
                          }];
    
    needMoreDataObserver = [[NSNotificationCenter defaultCenter] addObserverForName:NOTIFY_RECIVED_SLEEP_DATA
                                                                             object:nil
                                                                              queue:nil
                                                                         usingBlock:^(NSNotification *note)
                            {
                                [BlueToothLib requestSportData:0x08 withBlock:^(BOOL isTimeOut) {
                                    if (isTimeOut) {
                                        [subject sendNext:nil];
                                    }
                                }];
                            }];
    
    [BlueToothLib requestSportData:0x08 withBlock:^(BOOL isTimeOut) {
        if (isTimeOut) {
            [subject sendNext:nil];
        }
    }];
    
    return subject;
}

+(BOOL)dataIsValid:(NSData *)data
{
    Byte *byteData = (Byte *)[data bytes];
    for (int i = 0; i < [data length]; i++)
    {
        if (byteData[i] != 0XFF)
        {
            return YES;
        }
    }
    return data.length == 0;
}

+ (void)handleUnsafeSleepData:(NSMutableData *)mdata
{
    //处理这种不正确的数据,
    if (mdata.length < 8) {
        return;
    }
    int offset = mdata.length - 8;
    const void * data = mdata.bytes;
    
    uint32_t dateInterval;
    memcpy(&dateInterval, &data[offset], 4);
    // 在最后一个数据在时间上+1
    dateInterval += 1;
    offset += 4;
    
    //  人为添加一个结束
    uint8_t type = 0;
    offset += 1;
    
    uint8_t shake = 1;
    offset += 1;
    
    //reversed
    uint16_t reversed = 0;
    offset += 2;
    
    [mdata appendBytes:&dateInterval length:4];
    [mdata appendBytes:&type length:1];
    [mdata appendBytes:&shake length:1];
    [mdata appendBytes:&reversed length:2];
    [SRSportBleService processSleepData:mdata];
}

@end
